package com.example.logindemo.service.impl;

import com.example.logindemo.entity.RunOrder;
import com.example.logindemo.repository.RunOrderRepository;
import com.example.logindemo.service.RunOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class RunOrderServiceImpl implements RunOrderService {

    @Autowired
    private RunOrderRepository runOrderRepository;

    @Override
    @Transactional
    @CacheEvict(value = {"runOrders", "runOrderCounts"}, allEntries = true)
    public RunOrder createRunOrder(RunOrder runOrder) {
        runOrder.setCreateTime(new Date());
        runOrder.setUpdateTime(new Date());
        if (runOrder.getReviewStatus() == null) {
            runOrder.setReviewStatus("unreviewed");
        }
        return runOrderRepository.save(runOrder);
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "runOrders", key = "#id")
    public Optional<RunOrder> getRunOrderById(Integer id) {
        return runOrderRepository.findById(id);
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "runOrders", key = "'runOrderId:' + #runOrderId")
    public Optional<RunOrder> getRunOrderByRunOrderId(String runOrderId) {
        return runOrderRepository.findByRunOrderId(runOrderId);
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "runOrders", key = "'userId:' + #userId")
    public List<RunOrder> getRunOrdersByUserId(Integer userId) {
        return runOrderRepository.findByUserId(userId);
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "runOrders", key = "'all'")
    public List<RunOrder> getAllRunOrders() {
        return runOrderRepository.findAll();
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "runOrders", key = "'status:' + #status")
    public List<RunOrder> getRunOrdersByStatus(String status) {
        return runOrderRepository.findByStatus(status);
    }

    @Override
    @Transactional
    @CacheEvict(value = {"runOrders", "runOrderCounts"}, allEntries = true)
    public RunOrder updateRunOrder(RunOrder runOrder) {
        runOrder.setUpdateTime(new Date());
        return runOrderRepository.save(runOrder);
    }

    @Override
    @Transactional
    @CacheEvict(value = {"runOrders", "runOrderCounts"}, allEntries = true)
    public void updateRunOrderStatus(String runOrderId, String status) {
        Optional<RunOrder> runOrderOpt = runOrderRepository.findByRunOrderId(runOrderId);
        if (runOrderOpt.isPresent()) {
            RunOrder runOrder = runOrderOpt.get();
            runOrder.setStatus(status);
            runOrder.setUpdateTime(new Date());
            runOrderRepository.save(runOrder);
        }
    }

    @Override
    @Transactional
    @CacheEvict(value = {"runOrders", "runOrderCounts"}, allEntries = true)
    public void updateReviewStatus(String runOrderId, String reviewStatus) {
        Optional<RunOrder> runOrderOpt = runOrderRepository.findByRunOrderId(runOrderId);
        if (runOrderOpt.isPresent()) {
            RunOrder runOrder = runOrderOpt.get();
            runOrder.setReviewStatus(reviewStatus);
            runOrder.setUpdateTime(new Date());
            runOrderRepository.save(runOrder);
        }
    }

    @Override
    @Transactional
    @CacheEvict(value = {"runOrders", "runOrderCounts"}, allEntries = true)
    public void deleteRunOrder(Integer id) {
        runOrderRepository.deleteById(id);
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "runOrders", key = "'search:' + #keyword")
    public List<RunOrder> searchRunOrders(String keyword) {
        return runOrderRepository.searchRunOrders(keyword);
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "runOrderCounts", key = "'userId:' + #userId")
    public long countRunOrdersByUserId(Integer userId) {
        return runOrderRepository.countByUserId(userId);
    }

    @Override
    @Transactional(readOnly = true)
    @Cacheable(value = "runOrderCounts", key = "'completed:' + #userId")
    public long countCompletedRunOrdersByUserId(Integer userId) {
        return runOrderRepository.countByUserIdAndStatus(userId, "completed");
    }
}